package com.totoro.service.impl;

import com.totoro.mapper.ProductMapper;
import com.totoro.pojo.*;
import com.totoro.service.ProductService;
import com.totoro.utils.IKParticiple;
import com.totoro.utils.MapSort;
import lombok.SneakyThrows;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;

/**
 * @author TOTORO
 * @date 2021/7/7 18:25
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    ProductMapper productMapper;

    @Override
    public Integer addProduct(Product product) {
        return productMapper.addProduct(product);
    }

    @Override
    public Integer addProductSkus(Integer pid, JSONArray jsonArray, Integer[] productCounts, double[] productPrices) {
        if(jsonArray.size() <= 0){
            return 1;
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            ProductSpecs productSpecs = new ProductSpecs();
            // 获取属性，打包成对象
            productSpecs.setPid(pid);
            JSONObject job = jsonArray.getJSONObject(i);
            productSpecs.setProductSpaceData(job.toString());
            productSpecs.setProductStock(productCounts[i]);
            productSpecs.setProductPrice(productPrices[i]);
            productMapper.addProductSkus(productSpecs);
        }

        return 1;
    }

    @SneakyThrows
    @Override
    public Integer addProductImages(Integer pid, MultipartFile[] files, HttpServletRequest request) {
        //判断file数组不能为空并且长度大于0

        if (files != null && files.length > 0) {
            //循环获取file数组中得文件
            for (int i = 0; i < files.length; i++) {
                MultipartFile file = files[i];
                if(file.getSize() > 2*1024*1024){
                    throw new RuntimeException("文件大小要大于2M");
                }
                String uploadPath = request.getSession().getServletContext().getRealPath("/")+"static\\img\\product\\";
                System.out.println(uploadPath);
                File path =  new File(uploadPath);
                if(path == null){ path.mkdirs();}
                String ext =  file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                if(".jpg.png.jpeg.gif".indexOf(ext) == -1){
                    throw new RuntimeException("文件名称后缀不符合要求");
                }
                String filename = UUID.randomUUID().toString();
                // 通过MultipartFile的transferTo(File dest)这个方法来直接转存文件到指定的路径
                file.transferTo(new File(uploadPath+filename+file.getOriginalFilename()));
                // 打包成对象，交互dao
                ProductImage productImage = new ProductImage();
                productImage.setPid(pid);
                productImage.setImagePath("\\static\\img\\product\\"+filename+file.getOriginalFilename());
                productImage.setImageStatus(i+1);
                productMapper.addProductImages(productImage);
            }
        }


        return 1;
    }

    @Override
    public Integer updateProductStock(int type, int count, int pid) {
        return productMapper.updateProductStock(type, count, pid);
    }

    @Override
    public Integer updateSkuGroupStock(int type, int count, int psId) {
        return productMapper.updateSkuGroupStock(type, count, psId);
    }

    @Override
    public Product findProductById(int pid) {
        return productMapper.findProductById(pid);
    }

    @Override
    public Integer[] findAllProductId() {
        return productMapper.findAllProductId();
    }

    @Override
    public Integer findMinSkuIdByPid(int pid) {
        return productMapper.findMinSkuIdByPid(pid);
    }

    @Override
    public Integer findMaxSkuIdByPid(int pid) {
        return productMapper.findMaxSkuIdByPid(pid);
    }

    @Override
    public Map<Integer, ProductSpecs> findProductSkuNameById(int pid) {
        List<ProductSpecs> list = productMapper.findProductSkusById(pid);
        // 将数据封装在map中
        return ProductSpecsListMapperMap(list);
    }

    @Override
    public ProductSpecs findAssignSkuByPidAndSkuId(int skuId) {
        return productMapper.findAssignSkuByPidAndSkuId(skuId);
    }

    @Override
    public Map<Integer, ProductSpecs> findAssignSkusByPidAndSkuData(int pid, String skuData) {
        Map<Integer, ProductSpecs> map = ProductSpecsListMapperMap(productMapper.findAssignSkusByPidAndSkuData(pid, skuData));
        // 排序
        MapSort.sortByKey(map, false);

        return map;
    }

    @Override
    public List<ProductImage> findProductImagesById(int pid) {
        return productMapper.findProductImagesById(pid);
    }

    @Override
    public List<CollectProduct> findAllUserCollectProduct(int uid, String value) {
        return productMapper.findAllUserCollectProduct(uid, value);
    }

    @Override
    public CollectProduct checkUserCollectProduct(int uid, int pid) {
        return productMapper.checkUserCollectProduct(uid, pid);
    }

    @Override
    public Integer collectProduct(int uid, int pid) {
        return productMapper.collectProduct(uid, pid);
    }

    @Override
    public Integer cancelCollectProduct(int uid, int pid) {
        return productMapper.cancelCollectProduct(uid, pid);
    }

    @Override
    public Integer batchDeleteCollectProduct(Integer[] collectIds) {
        return productMapper.batchDeleteCollectProduct(collectIds);
    }

    @Override
    public Integer updateProductCollectCount(int type, int pid) {
        return productMapper.updateProductCollectCount(type, pid);
    }

    @Override
    public Integer batchReduceProductCollectCount(Integer[] collectIds) {
        return productMapper.batchReduceProductCollectCount(collectIds);
    }

    @Override
    public Integer addBuyShop(BuyShop buyShop) {
        return productMapper.addBuyShop(buyShop);
    }

    @Override
    public BuyShop checkUserBuyShop(BuyShop buyShop) {
        return productMapper.checkUserBuyShop(buyShop);
    }

    @Override
    public Map<Integer, List<BuyShop>> findAllUserBuyShop(int uid, int categoryId, String keyword, int curr) {
        Map<Integer, List<BuyShop>> map = new HashMap<>();
        List<BuyShop> list = productMapper.findAllUserBuyShop(uid, categoryId, keyword, curr);
        for (BuyShop buyShop : list) {
            map.put(buyShop.getProduct().getShop().getId(), new ArrayList<>());
        }
        for (BuyShop buyShop : list) {
            map.get(buyShop.getProduct().getShop().getId()).add(buyShop);
        }
        Map<Integer, List<BuyShop>> indexMap = new HashMap<>();
        int index = 0;
        for(List<BuyShop> v:map.values()){
            indexMap.put(index, v);
            index++;
        }
        return indexMap;
    }

    @Override
    public List<BuyShop> findAllUserBuyShopList(int uid, int categoryId, String keyword, int curr) {
        return productMapper.findAllUserBuyShop(uid, categoryId, keyword, curr);
    }

    @Override
    public Integer deleteBuyShop(int uid, int sid) {
        return productMapper.deleteBuyShop(uid, sid);
    }

    @Override
    public Integer addProductCommentCount(int pid) {
        return productMapper.addProductCommentCount(pid);
    }

    @Override
    public List<Product> findProductsByName(String productName, String sort, boolean isDiscount, int curr, double lowPrice, double highPrice, int belongCategoryId) {
        return productMapper.findProductsByName(productName, sort, isDiscount, curr, lowPrice, highPrice, belongCategoryId);
    }

    @Override
    public Integer findCategoryIdByPid(int pid) {
        return productMapper.findCategoryIdByPid(pid);
    }

    @Override
    public List<Product> findRecentRandHistoryProducts(int uid) {
        Integer[] integers = productMapper.findRecentRandHistoryProducts(uid);
        if(null == integers || integers.length < 1){
            return new ArrayList<Product>();
        }
        List<Product> products = productMapper.recommendPidFind(integers);
        List<String> finalStrings = new ArrayList<>();
        for (Product product : products) {
            // 使用分词器
            String[] splits = IKParticiple.participle(product.getProductName(), false);
            finalStrings.addAll(Arrays.asList(splits));
        }
        return productMapper.fuzzyFindProduct(finalStrings, 50);
    }

    @Override
    public List<Product> findHotRandHistoryProducts() {
        Integer[] integers = productMapper.findHotRandHistoryProducts();
        List<Product> products = productMapper.recommendPidFind(integers);
        List<String> finalStrings = new ArrayList<>();
        for (Product product : products) {
            // 使用分词器
            String[] splits = IKParticiple.participle(product.getProductName(), false);
            finalStrings.addAll(Arrays.asList(splits));
        }
        return productMapper.fuzzyFindProduct(finalStrings, 50);
    }

    @Override
    public List<Product> findKeywordAgoProducts() {
        Integer[] integers = productMapper.findHotRandHistoryProducts();
        List<Product> products = productMapper.recommendPidFind(integers);
        List<String> finalStrings = new ArrayList<>();
        for (Product product : products) {
            // 使用分词器
            String[] splits = IKParticiple.participle(product.getProductName(), false);
            finalStrings.addAll(Arrays.asList(splits));
        }
        return productMapper.fuzzyFindProduct(finalStrings, 50);
    }

    @Override
    public List<Product> recommendPidFind(Integer[] productIds) {
        return productMapper.recommendPidFind(productIds);
    }

    @Override
    public List<Product> fuzzyFindProduct(List<String> keywords, int productCount) {
        return productMapper.fuzzyFindProduct(keywords, productCount);
    }

    @Override
    public Integer[] getRandShopProduct(int sid, int notPid, int limitCount) {
        return productMapper.getRandShopProduct(sid, notPid, limitCount);
    }

    @Override
    public List<Product> findShopOtherProducts(int sid, int notPid, int limitCount) {
        return productMapper.findShopOtherProducts(sid, notPid, limitCount);
    }

    @Override
    public Integer updateProductClickCount(int pid) {
        return productMapper.updateProductClickCount(pid);
    }

    @Override
    public Integer updateCategoryClickCount(int cid) {
        return productMapper.updateCategoryClickCount(cid);
    }

    @Override
    public Integer updateProductDealCountByPid(int pid) {
        return productMapper.updateProductDealCountByPid(pid);
    }

    @Override
    public Integer updateProductPriceAndStockByPid(Product product) {
        return productMapper.updateProductPriceAndStockByPid(product);
    }

    @Override
    public Integer updateProductStatusByPid(int pid, boolean isUpdate, int status, boolean isDelete, int deleteStatus) {
        return productMapper.updateProductStatusByPid(pid, isUpdate, status, isDelete, deleteStatus);
    }

    @Override
    public Integer updateProductDeleteTime(int pid) {
        return productMapper.updateProductDeleteTime(pid);
    }

    @Override
    public Integer addProductRecover(int reasonId, int pid) {
        return productMapper.addProductRecover(reasonId, pid);
    }

    @Override
    public List<SearchTextList> findSearchText(String[] texts) {
        return productMapper.findSearchText(texts);
    }

    @Override
    public List<SearchTextList> findReturn(String value) {
        return productMapper.findReturn(value);
    }

    @Override
    public Integer addProductMonthDeal(Integer[] integers) {
        return productMapper.addProductMonthDeal(integers);
    }

    @Override
    public Integer updateProductMonthDeal(ProductMonthDeal productMonthDeal) {
        return productMapper.updateProductMonthDeal(productMonthDeal);
    }

    @Override
    public ProductMonthDeal findNowMonthIsHaveProductDeal(ProductMonthDeal productMonthDeal) {
        return productMapper.findNowMonthIsHaveProductDeal(productMonthDeal);
    }


    /**
     * 将Sku集合转换成Map
     * @param list
     * @return
     */
    private Map<Integer, ProductSpecs > ProductSpecsListMapperMap(List<ProductSpecs> list){
        Map<Integer, ProductSpecs> map = new TreeMap<>();
        for (ProductSpecs specs: list) {
            map.put(specs.getId(), specs);
        }
        return map;
    }
}
